<?php

/**
 * Shopdingyu供应商 SDK
 * @author chenyun
 */

namespace App\Service\VendorClient\Shopdingyu;
use App\Service\Code\Normal;
use App\Service\TaskServer\TaskWorker;
use Service\AppService\IdService;
use App\Model\PssModel\ServiceConfig;
use function GuzzleHttp\json_encode;
use App\Service\AppService\SystemCacheConfigService;
class ShopdingyuApiClient
{
    private $account  = 'Shopdingyu';
    protected $config;
    protected $RouteMap = [
        'createOrder'   => 'supplier.createsaleorder',
        'cancelOrder'   => 'supplier.cancelsaleorder',
    ];
    
    /**
     * 初始参数
     * @param obj $collection
     */
    public function __construct( $apiBody = [] ) 
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     */
    public function createOrder( $params = [] ) 
    {   
        if( empty($params['supplierOrder']) || empty($params['orderGoods']) || empty($params['order']) || empty($params['binfo']) ) {
            return Normal::returnCode(Normal::FAIL,"except param supplierOrder or orderGoods or order or binfo");
        }
        //组装订单参数
        $orderInfo = $params['supplierOrder'];
        $order     = $params['order'];
        $binfo     = $params['binfo'];
        $orderGoods = $params['orderGoods'];
        //商品下单组
        $orderItem = [];
        $productAmt = $TaxAmt = 0 ;
        foreach ($orderGoods as $key => $item ) 
        {
            //卖价
            $price              = $item['price'];
            //商品购买规格数量
            $spec_num           = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity           = $item['quantity'];
            //实际购买数量
            $buyAcount          = $spec_num * $quantity;
            
            //单个商品价格
            $singleGoodsPrice   = bcdiv((string)$price, (string)$spec_num,3);
            $singleGoodsPrice   = ceil(bcmul((string)$singleGoodsPrice,(string)'100',1));
            $singleGoodsPrice   = bcdiv($singleGoodsPrice,'100',2);
            //商品组
            $orderItem[] = [
                "ProductId"     => $item['supplier_skucode'],
                "SalePrice"     => $singleGoodsPrice,
                "Quantity"      => $buyAcount,
            ];
            $singleGoodsTotalPrice = bcmul((string)$singleGoodsPrice,(string)$buyAcount,2);
            $productAmt = bcadd((string)$productAmt,(string)$singleGoodsTotalPrice,2);
        }
        
        //实际下单金额 
        $real_total_money   = $orderInfo['real_total_money'];
        //运费
        $deliver_money      = $orderInfo['deliver_money'];
        //订单优惠金额 = 含税商品总金额  + 运费 -实际下单金额 
        $order_total_money  = bcadd((string)$productAmt,(string)$deliver_money,2);
        //优惠金额
        $discount_money     = bcsub((string)$order_total_money,(string)$real_total_money,2);
        
        //下单支付的时候支付信息
        $apply_extends  = @json_decode($orderInfo['apply_extends'],true);
        $payTime        = empty($order['payTime']) ? $orderInfo['pay_time'] :$order['payTime'];
        //支付时间
        $pay_time       = $payTime ? $payTime : time();
        $pay_time       = date('Y-m-d H:i:s',$payTime);     
        //支付流水号
        $pay_sn         = $order['paySerial'] ?? $orderInfo['pay_sn'];
        
        //获取上游供应商支付方式路由
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $PayCompanyCode = $order['payCommanyCode'] ? $order['payCommanyCode'] : $payCommanyCode;
        
        //电商平台信息
        $enterpriseNum = $apply_extends['enterpriseNum'] ?? '';
        $enterpriseName = $apply_extends['enterpriseName'] ?? '';
        $enterpriseNum = $order['enterpriseNum'] ? $order['enterpriseNum'] : $enterpriseNum;
        $enterpriseName = $order['enterpriseName'] ? $order['enterpriseName'] : $enterpriseName;
        
        //获取支付方式配置
        $pay_value = ServiceConfig::instance()->getConfigByEventsValue('shopdingyu', ServiceConfig::TYPE_PAY, $PayCompanyCode);
        if (empty($pay_value)) {
            return Normal::returnCode(Normal::FAIL, "鼎裕供应商当前不支持支付方式：{$PayCompanyCode}");
        }
        
        //交易订单号
        $order_sn = $orderInfo['supplier_dsn'];
        
        
        //商品类型
        $item = current($orderGoods);
        $tradeMap = [
            '0' => '3',
            '1' => '1',
            '2' => '0'
        ];
        
        //缓存配置
        $config = SystemCacheConfigService::instance()->getCacheInfoBySystemCode('sysconfig');
        if( empty($config['NotifyUrl']) ) {
            return Normal::returnCode(Normal::FAIL, "系统管理-业务配置-系统配置对应NotifyUrl不能为空");
        }
        
        //请求数据
        $data = [
            'SourceOrderId'             => $order_sn,
            'CustomsOrderId'            => $order_sn,
            'TradeType'                 => $tradeMap[$item['goods_type']],
            'OrderType'                 => 1,
            'SODeclareType'             => 0,
            'CustomsPriceType'          => 1,
            'SOAmount'                  => $order_total_money,
            'ProductAmount'             => $productAmt,
            'FreightAmount'             => $deliver_money,
            'PayAmount'                 => $real_total_money,
            'DiscountAmount'            => $discount_money,
            'Tax'                       => '0.00',
            'PayTypeSysNo'              => $pay_value,
            'PaySerialNumber'           => $pay_sn,
            'DeclarePaySerialNumber'    => $pay_sn,
            'DeclarePlatformCustomCode' => $enterpriseNum,
            'PayDate'              		=> $pay_time,
            'OrderDate'            		=> date("Y-m-d H:i:s",$orderInfo['cd']),
            'IDCardName'           		=> $orderInfo['buyer_realname'],
            'IDCardNumber'         		=> $orderInfo['buyer_idcard'],
            'RealPhone'            		=> $orderInfo['buyer_phone'],
            'FullReceiveAddress'   		=> implode("", [$orderInfo['province'],$orderInfo['city'],$orderInfo['district'],$orderInfo['receive_address']]),
            'ReceiveAddress'       		=> $orderInfo['receive_address'],
            'ReceiveName'          		=> $orderInfo['receive_name'],
            'ReceivePhone'         		=> $orderInfo['recveive_phone'],
            'Memo'                 		=> $orderInfo['order_remark'] ? $orderInfo['order_remark'] : '尽快发货',
            'StoreSysNo'           		=> $this->config['StoreSysNo'],
            'ExpressSysNo'         		=> $this->config['ExpressSysNo'],
            'CallbackUrl'               => $config['NotifyUrl'].'/Notify/index/userType/shopdingyu/messageType/OrderExpress',
            'ItemList'             		=> $orderItem
        ];
        
        $result = $this->execute('createOrder',['SaleOrderCreateParamList'=>[$data]]);
        if( $result['code'] == Normal::SUC ) 
        {
            $errMsg = json_encode($result['data'],JSON_UNESCAPED_UNICODE);
            if( empty($result['data']['Data']) ) {
                return Normal::returnCode(Normal::FAIL,"订单推送失败【{$errMsg}】");
            }
            
            $result_order = current($result['data']['Data']);
            if( isset($result_order['IsCreateSuccess']) && $result_order['IsCreateSuccess'] == true) {
                return Normal::returnCode(Normal::SUC,"订单推送成功",[
                    'thirdpart_order_sn' => $result_order['SaleOrderSysNo']
                ]);
            }
            
            $errMsg = json_encode($result['data'],JSON_UNESCAPED_UNICODE);
            return Normal::returnCode(Normal::FAIL,"订单推送失败【{$errMsg}】");
        }
        
        return $result;
    }
   
    /**
     * 获取取消订单
     */
    public function cancelOrder( $params = [] ) 
    {
        if (empty($params['supplierOrder'])) {
            return Normal::returnCode(Normal::FAIL, "except param supplierOrder");
        }        
        $data = [
            'SaleOrderSysNo'    => (int)$params['supplierOrder']['thirdpart_order_sn']
        ];
        
        $result = $this->execute('cancelOrder', $data);
        if( $result['code'] == Normal::SUC )
        {
            if( isset($result['data']['Data']['IsSuccess']) && $result['data']['Data']['IsSuccess'] == true) {
                return Normal::returnCode(Normal::SUC,"取消订单成功");
            }
        
            $errMsg = json_encode($result,JSON_UNESCAPED_UNICODE);
            return Normal::returnCode(Normal::FAIL,"订单推送失败【{$errMsg}】");
        }
        
        return $result;
    }
    
    /**
     * 加签
     * @param string $method
     * @param array $param
     */
    protected function getSign(string $method,array $param)
    {
       $data = [
           'method'     => $this->RouteMap[$method],
           'appid'      => $this->config['appid'],
           'sign_type'  => 'md5',
           'data'       => json_encode($param,JSON_UNESCAPED_UNICODE),
           'version'    => '1.0'
       ];
       $implodes = [];
       ksort($data);
       foreach ($data as $key => $value) {
           $implodes[] = "{$key}={$value}";
       }
       
       $str = \implode("&", $implodes)."&appsecret={$this->config['appsecret']}";
       $str = strtolower($str);
       $data['sign'] = md5($str);
       return $data;
    }
    
    /**
     * 开始执行请求
     * @param string $method
     * @param array $param
     * @return unknown[]|string[]|array[]
     */
    public function execute(string $method,array $param)  
    {
        if( empty($param) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        
        $signArr = $this->getSign($method,$param);
        $url = $this->config['URL'];
        $parameter = [
            [
                'tag'       => $this->account.'_'.$method,
                'uid'       => IdService::instance()->getOtherID(),
                'url'       => $url,
                'data'      => $signArr,
                'method'    => 'POST',
                'format'    => 'x-www-form-urlencoded',
                'header'    => [],
        
            ],
        ];
        
        $resTask = TaskWorker::instance()->addTask($parameter);
        $resTask = current($resTask);
        $res     = $resTask['response']['result'];
        $resHttp = json_decode($res,true);
        if( isset($resHttp['Code']) && $resHttp['Code'] == '0' && isset($resHttp['Success']) && $resHttp['Success'] == true ) {
            return Normal::returnCode(Normal::SUC,"成功",$resHttp);
        }
        
        return Normal::returnCode(Normal::FAIL,$res);
    }
}